package com.cstam.dao;

import java.util.ArrayList;
import java.util.List;

import javax.sql.DataSource;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.simple.ParameterizedBeanPropertyRowMapper;
import org.springframework.stereotype.Repository;

import com.cstam.domain.User;

@Repository//("userDao")
public class UserDao{
	
	private static Logger LOG = Logger.getLogger(UserDao.class);
	//private DataSource dataSource;
	private JdbcTemplate jdbcTemplate;

	@Autowired
	//@Qualifier("dataSource")
	public void setDataSource(DataSource dataSource) {
		//this.dataSource = dataSource;
		this.jdbcTemplate = new JdbcTemplate(dataSource);
	}

	public List<User> getUsers() {
		List<User> users = query("SELECT * FROM cstam.user",
				ParameterizedBeanPropertyRowMapper.newInstance(User.class));
		return users;
	}
	
	public User getUserByIduser(int iduser) {
		List<User> users = query("SELECT * FROM cstam.user WHERE iduser = ? ",
				ParameterizedBeanPropertyRowMapper.newInstance(User.class),
				new Object[] { iduser });

		if (users.size() > 0)
			return users.get(0);
		else
			return null;
	}

	public User getUserByUsername(String username) {
		//this must query one, otherwise throw exception
		/*User user = jdbcTemplate.queryForObject("SELECT * FROM cstam.user WHERE username = ? ", 
				ParameterizedBeanPropertyRowMapper.newInstance(User.class),
				new Object[] { username });*/
		List<User> users = query("SELECT * FROM cstam.user WHERE username = ? ",
				ParameterizedBeanPropertyRowMapper.newInstance(User.class),
				new Object[] { username });

		if (users.size() > 0)
			return users.get(0);
		else
			return null;
	}
	
	public int createUser(User user) {
		User user2=getUserByUsername(user.getUsername());
		if(user2!=null)
			return 0;
		int ret = update("INSERT INTO cstam.user (nickname, password, type ) VALUES (?, ?, ?)",
				new Object[] {user.getUsername(), user.getPassword(), user.getType()});
		return ret;
	}

	public int deleteUser(User user) {
		int ret = update("DELETE FROM cstam.user where iduser = ?",
				new Object[] { user.getIduser()	});
		return ret;
	}
	
	public int grantPermission(int type, int iduser) {
		int ret = update("UPDATE cstam.user SET type = ? where iduser = ?",
				new Object[] { type, iduser	});
		return ret;
	}
	
	public int login(String username, String pwd){
		User user= getUserByUsername(username);
		if(user!=null){
			String pwd2=user.getPassword();
			if(pwd==pwd2)
				return 1;
			else
				return 0;
		}
		else
			return 2;
	}
	
	public boolean changePwd(int userid,String oldpwd, String newpwd){
		User user = getUserByIduser(userid);
		if(user!=null){
			if(oldpwd==user.getPassword()){
				int ret = update("UPDATE cstam.user SET password = ? where iduser = ?",
						new Object[] { newpwd, userid });
				if(ret>0)
					return true;
				else
					return false;
			}
			else
				return false;
		}
		return false;
	}
	
	/**************************************
	 * Wrapper for Logger
	 **************************************/
	public <T> List<T> query(String sql, RowMapper<T> rowMapper, Object... args) throws DataAccessException {
		try {
			String args_str = "";
			for (Object o: args) {
				if (o == null) {
					args_str += "null ";
				} else {
					args_str += o.toString();
				}
			}
			LOG.info("query sql " + sql + " (with args: " + args_str + ")");
			return this.jdbcTemplate.query(sql, rowMapper, args);
		} catch (DataAccessException e) {
			e.printStackTrace();
			LOG.error(e.getMessage());
			throw e;
		}
	}
	
	public int update(String sql, Object ... args) throws DataAccessException {
		try {
			String args_str = "";
			for (Object o: args) {
				if (o == null) {
					args_str += "null ";
				} else {
					args_str += o.toString();
				}
			}
			//LOG.info("update sql " + sql + " (with args: " + args_str + ")");
			return this.jdbcTemplate.update(sql, args);
		} catch (DataAccessException e) {
			e.printStackTrace();
			//LOG.error(e.getMessage());
			throw e;
		}
	}

}
